package com.notary.util;

import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.notary.entity.vo.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.*;
import java.util.*;

/**
 * @author yjz
 * @date 2020-05-120 http工具类
 */
@Slf4j
public class HttpUtil {

    private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(15000).setConnectTimeout(15000)
            .setConnectionRequestTimeout(15000).build();

    public static final String DEF_CHATSET = "UTF-8";
    public static final int DEF_CONN_TIMEOUT = 30000;
    public static final int DEF_READ_TIMEOUT = 30000;
    public static String userAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36";

    /**
     * 发送 get请求Http
     *
     * @param url
     * @param param
     * @return
     */
    public static String doHttpGet(String url, Map<String, String> param, String token) {
        log.info(url);
        log.info(token);
        URIBuilder builder = null;
        HttpGet httpGet = null;
        try {
            builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();
            // 创建http GET请求
            httpGet = new HttpGet(uri);
            httpGet.setConfig(requestConfig);
            if (token != null) {
                httpGet.setHeader("Authorization", token);
            }
        } catch (URISyntaxException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }

        return doHttpGet(httpGet);
    }

    /**
     * 发送Get请求
     *
     * @param httpGet
     * @return
     */
    private static String doHttpGet(HttpGet httpGet) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        try {
            // 创建默认的httpClient实例.
            httpClient = HttpClients.createDefault();
            // 执行请求
            response = httpClient.execute(httpGet);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 关闭连接,释放资源
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseContent;
    }

    /**
     * @param strUrl 请求地址
     * @param params 请求参数
     * @param method 请求方法
     * @return 网络请求字符串
     * @throws Exception
     */
    public static String net(String strUrl, Map params, String method) throws Exception {
        HttpURLConnection conn = null;
        BufferedReader reader = null;
        String rs = null;
        try {
            StringBuffer sb = new StringBuffer();
            if (method == null || method.equals("GET")) {
                strUrl = strUrl + "?" + urlencode(params);
            }
            URL url = new URL(strUrl);
            conn = (HttpURLConnection) url.openConnection();
            if (method == null || method.equals("GET")) {
                conn.setRequestMethod("GET");
            } else {
                conn.setRequestMethod("POST");
                conn.setDoOutput(true);
            }
            conn.setRequestProperty("User-agent", userAgent);
            conn.setUseCaches(false);
            conn.setConnectTimeout(DEF_CONN_TIMEOUT);
            conn.setReadTimeout(DEF_READ_TIMEOUT);
            conn.setInstanceFollowRedirects(false);
            conn.connect();
            if (params != null && method.equals("POST")) {
                try {
                    DataOutputStream out = new DataOutputStream(conn.getOutputStream());
                    out.writeBytes(urlencode(params));
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }
            InputStream is = conn.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, DEF_CHATSET));
            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sb.append(strRead);
            }
            rs = sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                reader.close();
            }
            if (conn != null) {
                conn.disconnect();
            }
        }
        return rs;
    }

    // 将map型转为请求参数型
    public static String urlencode(Map<String, String> data) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry i : data.entrySet()) {
            try {
                sb.append(i.getKey()).append("=").append(URLEncoder.encode(i.getValue() + "", "UTF-8")).append("&");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    public static JsonResult doPost(String url, Map<String, String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String result = "";
        JsonResult resultVo = null;
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, (String) param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
                httpPost.setEntity(entity);
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity(), "UTF-8");
                return JsonResult.success(result);
            } else {
                result = response.getStatusLine().getStatusCode() + "";
                return JsonResult.fail(result);
            }
        } catch (Exception e) {
            result = "发送 POST 请求出现异常！" + e;
            resultVo = JsonResult.fail(result);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
                result = "发送 POST 请求出现异常！" + e;
                resultVo = JsonResult.fail(result);
            }
        }
        return resultVo;
    }

    public static JsonResult doPostJson(String url, String json) {
        try {
            HttpResponse res = HttpRequest.post(url)
                    .header("connection", "Keep-Alive")
//                    .header("Accept", "application/json;charset=UTF-8")
                    .header("Content-Type", "application/json;charset=utf-8")
                    .body(json)
                    .execute();
            if (res.getStatus() == HttpStatus.SC_OK) {
//                String charset = res.charset();
                String result = UnicodeUtil.toString(res.body());
                log.info("post请求结果：" + result);
                return JsonResult.success(result);
            } else {
                log.info("post请求失败结果：" + res.toString());
                return JsonResult.fail(res.getStatus() + "");
            }

        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.fail(e.getMessage() + "");
        }
    }

    public static JsonResult postFilesByFile(String filePostUrl, String tokenHeader,
                                             Map<String, String> params, File file) {

        HttpPost httppost = new HttpPost(filePostUrl);
        CloseableHttpClient client = HttpClients.createDefault();
        if (tokenHeader != null)
            httppost.setHeader("Authorization", tokenHeader);
        CloseableHttpResponse response = null;
        String result = "";
        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
        //
        //文件
        entityBuilder.addBinaryBody("file", file,
                ContentType.APPLICATION_OCTET_STREAM, file.getName());
        // 是否有表单参数
        if (params != null) {
            for (String key : params.keySet()) {
                entityBuilder.addTextBody(key, params.get(key), ContentType.TEXT_PLAIN.withCharset("UTF-8"));
            }
        }
        httppost.setEntity(entityBuilder.build());
        try {
            // 执行http请求
            response = client.execute(httppost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(response.getEntity(), "UTF-8");
                return JsonResult.success(result);
            } else {
                result = response.getStatusLine().getStatusCode() + "";
                return JsonResult.fail(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
            result = "发送 POST 请求出现异常！" + e;
            return JsonResult.fail(result);
        } finally {
            client.getConnectionManager().shutdown();
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                result = "发送 POST 请求出现异常！" + e;
                return JsonResult.fail(result);
            }
        }
    }


    public static JsonResult doShortUrl(String longUrl, Integer type) {
        String url = "https://v1.alapi.cn/api/url";
//        String url1 = "http://ynsign.oss-cn-hangzhou.aliyuncs.com/user/WGSuno69/20200707/20200707113326.pdf?Expires=1634443753&OSSAccessKeyId=LTAI4Fdmnk1qK5eygER7QUoH&Signature=NZ3oRYmydcrGUc5Wx%2BBkWZaRFqU%3D";
//        System.out.println(url);
        HttpResponse res = HttpRequest.post(url)
//                    .header("connection", "Keep-Alive")
                .header("Content-Type", "application/x-www-form-urlencoded")
//                    .header("Content-Type", "application/json;charset=utf-8")
                .form("url", longUrl)
                .form("type", type)//4
                .execute();
        if (res.getStatus() == HttpStatus.SC_OK) {
            String result = UnicodeUtil.toString(res.body());
            JSONObject jsonObject = JSON.parseObject(result);
            if (jsonObject.containsKey("data")) {
                JSONObject data = jsonObject.getJSONObject("data");
                if (data.containsKey("short_url")) {
                    return JsonResult.success(data.getString("short_url"));
                }
            }
            return JsonResult.fail();
        } else {
            return JsonResult.fail();
        }
    }

    /**
     * 根据长网址获取百度短网址内容
     *
     * @param dwzUrl
     * @param videoUrl
     * @param dwzToken
     * @param dwzValidDate
     * @return
     */
    public static JsonResult getShortUrl(String dwzUrl, String videoUrl, String dwzToken, String dwzValidDate) {
        JSONArray jsonArray = new JSONArray();
        Map<String, String> params = new HashMap<>(2);
        params.put("LongUrl", videoUrl);
        params.put("TermOfValidity", dwzValidDate);
        jsonArray.add(params);
        try {
            HttpResponse res = HttpRequest.post(dwzUrl)
                    .header("Dwz-Token", dwzToken)
                    .body(jsonArray.toJSONString(), "application/json")
                    .execute();
            if (res.getStatus() == HttpStatus.SC_OK) {
                String result = UnicodeUtil.toString(res.body());
                JSONObject jsonObject = JSON.parseObject(result);
                if (Objects.equals(0, jsonObject.get("Code"))) {
                    JSONArray resultArr = (JSONArray) jsonObject.get("ShortUrls");
                    String shortUrl = resultArr.getJSONObject(0).get("ShortUrl").toString();
                    return JsonResult.success(shortUrl);
                }
                log.info("获取百度短网址失败结果：" + res.toString());
                return JsonResult.fail();
            } else {
                log.info("获取百度短网址失败结果：" + res.toString());
                return JsonResult.fail();
            }
        } catch (HttpException e) {
            e.printStackTrace();
            log.info("获取百度短网址失败结果：" + e);
            return JsonResult.fail();
        }
    }
}
